﻿using Furion;
using Furion.DataValidation;
using Furion.DependencyInjection;
using Furion.UnifyResult;
using Furion.UnifyResult.Internal;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Threading.Tasks;

namespace GWB.Core.Common
{
    
    /// <summary>
    ///  风格返回值
    /// </summary>
    [SuppressSniffer, UnifyModel(typeof(UnifyResult<>))]
    public class ResultProvider : IUnifyResultProvider
    {
        /// <summary>
        /// 异常返回值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="metadata"></param>
        /// <returns></returns>
        public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
        {
            context.ExceptionHandled = true;
            return new JsonResult(Result(metadata.StatusCode, isSuccess: false, msg: "请求失败", errors: metadata.Errors));
        }

        /// <summary>
        /// 成功返回值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public IActionResult OnSucceeded(ActionExecutedContext context, object data)
        {
            return new JsonResult(Result(StatusCodes.Status200OK, true, data, msg: "请求成功"));
        }

        /// <summary>
        /// 验证失败返回值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="metadata"></param>
        /// <returns></returns>
        public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
        {
            return new JsonResult(Result(StatusCodes.Status400BadRequest, msg: "参数错误", errors: metadata.ValidationResult));
        }

        /// <summary>
        /// 特定状态码返回值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="statusCode"></param>
        /// <param name="unifyResultSettings"></param>
        /// <returns></returns>
        public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings)
        {
            // 设置响应状态码
            UnifyContext.SetResponseStatusCodes(context, statusCode, unifyResultSettings);
            switch (statusCode)
            {
                // 处理 401 状态码
                case StatusCodes.Status401Unauthorized:
                    await context.Response.WriteAsJsonAsync(Result(statusCode, isSuccess: false, errors: "401 Unauthorized")
                        , App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
                    break;
                // 处理 403 状态码
                case StatusCodes.Status403Forbidden:
                    await context.Response.WriteAsJsonAsync(Result(statusCode, isSuccess: false, errors: "403 Forbidden")
                        , App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
                    break;
                default:
                    await context.Response.WriteAsJsonAsync(Result(statusCode, isSuccess: false, errors: statusCode)
                      , App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
                    break;
            }
        }

        /// <summary>
        /// 返回  风格结果集
        /// </summary>
        /// <param name="code"></param>
        /// <param name="isSuccess"></param>
        /// <param name="data"></param>
        /// <param name="msg"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        private static UnifyResult<object> Result(int code, bool isSuccess = default, object data = default, string msg = default, object errors = default)
        {
           

            var result= new UnifyResult<object>
            {
                Code = code,
                IsSuccess = isSuccess,
                Data = data,
                Errors = errors,
                Msg = msg,
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            };


            if (data!=null&&(data.GetType().Name== typeof(Result<>).Name|| data.GetType().Name == typeof(Result).Name))
            {
                var obj = data.Adapt<Result<object>>();
                result.IsSuccess = code== StatusCodes.Status200OK? obj.IsSuccess: isSuccess;
                result.Msg = string.IsNullOrWhiteSpace(obj.Msg) ? (code == StatusCodes.Status200OK ? "成功": obj.IsSuccess ? "成功" : "失败") : obj.Msg;
                result.Data = obj.Data;

            }
            ////判断object是否为泛型（不适用其他类型会报错）
            //if (data.GetType().GetGenericTypeDefinition() ==typeof(Result<object>).GetGenericTypeDefinition())
            //{
            //    var obj = data.Adapt<Result<object>>(); ;
            //    result.IsSuccess = obj.IsSuccess;
            //    result.Msg =string.IsNullOrWhiteSpace(obj.Msg) ? (obj.IsSuccess?"成功":"失败"): obj.Msg;
            //    result.Data = obj.Data;
            //}

            return result;
        }
    }
}